#pragma once

#include "Event.h"

class EventScheduler
{
public:
						EventScheduler(EventChannel* channel);
						~EventScheduler();

public:
	void				StepTick();

public:
	void				ScheduleAfter(uint tickAfter, Event* evt, IEventHandler* to);
	void				CancleFor(IEventHandler* handler);

private:
	struct Entry
	{
		uint			Tick;
		Event*			Event;
		IEventHandler*	To;

		struct less 
		{
			bool operator () (const Entry& a, const Entry& b) { return a.Tick < b.Tick; }
		};
	};

	uint				m_LocalTick;
	EventChannel*		m_Channel;

	typedef TPriorityQueue<Entry, Entry::less> ScheduleQueue;
	ScheduleQueue		m_Queue;
};

////////////////////////////////////////////////////////////

class EventRecorder
{
public:
};

////////////////////////////////////////////////////////////

class EventPlayback
{
};

////////////////////////////////////////////////////////////

class EventRepeater : public IEventHandler
{
public:
					EventRepeater(EventChannel* to) : m_Channel(to) {}

public:
	virtual void	OnEvent(Event* evt)			{m_Channel->Broadcast(evt);}

private:
	EventChannel*	m_Channel;
};

/*

#include "../script/LuaWrap.h"

class LuaEventExport
{
public:
LuaEventExport(lua_State* L) : L(L)		{ }

public:
template <class TValue>
LuaEventExport&			operator >> (const TValue& value)		{ LuaWrap::Push(L, value); return *this; }

template <class TRefObject>
LuaEventExport&			operator >> (const Ref<TRefObject>& v)	{ LuaWrap::Push(L, (TRefObject*)v); return *this; }

template <class TRefObject>
LuaEventExport&			operator >> (const NiPointer<TRefObject>& v)	{ LuaWrap::Push(L, (TRefObject*)v); return *this; }

LuaEventExport&			operator >> (float v)					{ lua_pushnumber(L, v); return *this; }
LuaEventExport&			operator >> (int v)						{ lua_pushinteger(L, v); return *this; }
LuaEventExport&			operator >> (uint v)					{ lua_pushinteger(L, v); return *this; }
LuaEventExport&			operator >> (const BitSet& v)			{ lua_pushinteger(L, v); return *this; }
LuaEventExport&			operator >> (const char* v)				{ lua_pushstring(L, v); return *this; }
LuaEventExport&			operator >> (const NiFixedString& v)	{ lua_pushstring(L, (const char*)v); return *this; }
LuaEventExport&			operator >> (const std::string& v)		{ lua_pushstring(L, v.c_str()); return *this; }
LuaEventExport&			operator >> (const NiString& v)			{ lua_pushstring(L, (const char*)v); return *this; }
LuaEventExport&			operator >> (bool v)					{ lua_pushboolean(L, v); return *this; }

private:
lua_State*				L;
};

////////////////////////////////////////////////////////////

class LuaEventImport
{
public:
LuaEventImport(lua_State* L, int arg) : L(L), arg(arg), errarg(0) { }

public:
template <class TValue>
LuaEventImport&			operator >> (TValue& v)					{ if (errarg) return *this; TValue* p = LuaWrap::ToPointer<TValue>(L, ++arg); if (p != NULL) v = *p; else errarg = arg; return *this; }

template <class TRefObject>
LuaEventImport&			operator >> (Ref<TRefObject>& v)
{ 
if (errarg) return *this;
if (lua_isnil(L, ++arg)) { v = NULL; return *this; }
TRefObject** p = LuaWrap::ToPointer<TRefObject*>(L, arg); 
if (p != NULL) v = *p; else errarg = arg; 
return *this; 
}

template <class TRefObject>
LuaEventImport&			operator >> (NiPointer<TRefObject>& v)
{
if (errarg) return *this;
if (lua_isnil(L, ++arg)) { v = NULL; return *this; }
TRefObject** p = LuaWrap::ToPointer<TRefObject*>(L, arg); 
if (p != NULL) v = *p; else errarg = arg; 
return *this; 
}

LuaEventImport&			operator >> (float& v)					{ if (errarg) return *this; if (lua_isnumber(L, ++arg)) v = (float)lua_tonumber(L, arg); else errarg = arg; return *this; }
LuaEventImport&			operator >> (int& v)					{ if (errarg) return *this; if (lua_isnumber(L, ++arg)) v = lua_tointeger(L, arg); else errarg = arg; return *this; }
LuaEventImport&			operator >> (uint& v)					{ if (errarg) return *this; if (lua_isnumber(L, ++arg)) v = (uint)lua_tointeger(L, arg); else errarg = arg; return *this; }
LuaEventImport&			operator >> (BitSet& v)					{ if (errarg) return *this; if (lua_isnumber(L, ++arg)) v = lua_tointeger(L, arg); else errarg = arg; return *this; }
LuaEventImport&			operator >> (const char*& v)			{ if (errarg) return *this; if (lua_isstring(L, ++arg)) v = lua_tostring(L, arg); else errarg = arg; return *this; }
LuaEventImport&			operator >> (NiFixedString& v)			{ if (errarg) return *this; if (lua_isstring(L, ++arg)) v = lua_tostring(L, arg); else errarg = arg; return *this; }
LuaEventImport&			operator >> (std::string& v)			{ if (errarg) return *this; if (lua_isstring(L, ++arg)) v = lua_tostring(L, arg); else errarg = arg; return *this; }
LuaEventImport&			operator >> (NiString& v)				{ if (errarg) return *this; if (lua_isstring(L, ++arg)) v = lua_tostring(L, arg); else errarg = arg; return *this; }
LuaEventImport&			operator >> (bool& v)					{ if (errarg) return *this; v = lua_toboolean(L, ++arg) != 0; return *this; }

public:
lua_State*				GetLuaState()							{ return L; }
int						GetArg()								{ return arg; }
int						GetArgError()							{ return errarg; }

private:
lua_State*				L;
int						arg;
int						errarg;
};

////////////////////////////////////////////////////////////

#define DEF_EVENT_LUA_EXPORT(STMT) \
virtual void Export(LuaEventExport& l) { l >> STMT ; } \
virtual void Import(LuaEventImport& l) { l >> STMT ; } 

*/